<template>
  <view class="sv-exam" :style="'--card-header-height:' + cardHeaderHeight">
    <!-- 顶部自定义导航 -->
    <template v-if="showExam">
      <!-- 答题区域 -->
      <!-- #ifdef VUE2 -->
      <exam-paper :paper.sync="curPaper" :examPaperId="examPaperId"></exam-paper>
      <exam-card v-if="showCard" :paper.sync="curPaper" :total="total"></exam-card>
      <!-- #endif -->
      <!-- #ifdef VUE3 -->
      <exam-paper v-model:paper="curPaper" :examPaperId="examPaperId"></exam-paper>
      <exam-card v-if="showCard" v-model:paper="curPaper"></exam-card>
      <!-- #endif -->
      <!-- 答题卡区域 -->
    </template>
    <view class="exam-empty-loading" v-else>
      <view class="exam-loading-cube"></view>
      <view class="exam-loading-text">加载中...</view>
    </view>
    <!-- 退出拦截 - 背题模式不做拦截 -->
    <!-- <sv-intercept-back v-if="type !== config.examTypeDict[0]"></sv-intercept-back> -->
  </view>
</template>

<script>
  import ExamCard from './exam-card.vue'
  import ExamPaper from './exam-paper.vue'
  import config from '@/uni_modules/sv-exam-plus/config.js'
  import {
    copyright
  } from '@/uni_modules/sv-exam-plus/utils/index.js'
  import store from '@/uni_modules/sv-exam-plus/store/index.js'

  export default {
    components: {
      ExamCard,
      ExamPaper
    },
    props: {
      /**
       * 三种答题模式
       * recite 背题模式 题库中顺序出题，带有答案，只需看题背答案，无需手动写题，可继续背题
       * practice 刷题模式 题库中顺序出题，答题完自动批改对错并给出答案，可继续或重新答题
       * exam 模拟考试 题库中随机抽取指定数量道题并打乱顺序，提交后自动批改，退出考试时弹出提示，时间到自动交卷
       */
      type: {
        type: String,
        default: ''
      },
      lib: {
        type: String,
        default: ''
      },
      data: {
        type: Array,
        default: () => []
      },
      favs: {
        type: Array,
        default: () => []
      },
      // 是否显示答题卡
      showCard: {
        type: Boolean,
        default: true
      },
      examPaperId: {
        type: Number,
        default: null
      }

    },
    data() {
      return {
        config, // 兼容写法，需要先声明否则报错
        cardHeaderHeight: '50px', // 根据是否显示答题卡，动态改变试题内容盒子高度
        curPaper: {}, // 初始默认题目
        showExam: false, // 题目是否加载完成
        total: null
      }
    },
    computed: {
      examData: {
        set(newData) {
          store.commit('updateData', newData)
        },
        get() {
          return store.state.examData
        }
      },
      examType: {
        set(newType) {
          store.commit('updateType', newType)
        },
        get() {
          return store.state.examType
        }
      },
      examFavs: {
        set(newFavs) {
          store.commit('updateFavs', newFavs)
        },
        get() {
          return store.state.examFavs
        }
      },
      examIndex: {
        set(newIndex) {
          store.commit('updateIndex', newIndex)
        },
        get() {
          return store.state.examIndex
        }
      }
    },
    watch: {
      // 监听考试类型改变
      'type': {
        handler(newType) {
          store.commit('updateType', newType)
          store.commit('updateIndex', this.getIndex())
          this.curPaper.index = this.examIndex === -1 ? 0 : this.examIndex
          // this.curPaper = { data: this.examData[this.examIndex], index: this.examIndex }
          const storage = uni.getStorageSync('sv-exam')
          uni.setStorageSync('sv-exam', Object.assign({
            ...storage
          }, {
            examType: newType
          }))
        },
        immediate: true
      },
      // 监听题目加载完成
      'data': {
        handler(newData) {
          store.commit('updateData', newData)
          store.commit('updateNum')
          this.curPaper.data = this.examData || []
          if (newData.length > 0) this.showExam = true
        },
        immediate: true
      },
      // 监听收藏
      'favs': {
        handler(newFavs) {
          store.commit('updateFavs', newFavs)
        }
      },
      'curPaper.index': {
        handler(newIndex) {
          this.setIndex(newIndex)
          this.$emit('changePaper', this.curPaper)
        }
      }
    },
    created() {
      this.init()
      copyright()
    },
    // #ifdef VUE2
    beforeDestroy() {
      this.$emit('quit', this.examData)
    },
    // #endif
    // #ifdef VUE3
    beforeUnmount() {
      this.$emit('quit', this.examData)
    },
    // #endif
    methods: {
      // 初始化
      async init() {
        this.cardHeaderHeight = this.showCard ? '50px' : '0px'
        store.commit('updateType', this.type)
        store.commit('updateData', this.data)
        store.commit('updateFavs', this.favs)
        store.commit('updateIndex', this.getIndex())
        store.commit('updateNum')
        this.curPaper = {
          data: this.examData[this.examIndex],
          index: this.examIndex
        }
      },
      setIndex(newIndex) {
        if (!this.lib) return
        const storage = uni.getStorageSync('sv-exam')
        switch (this.type) {
          case this.config.examTypeDict[0]:
            storage[this.lib] = Object.assign({
              ...storage[this.lib]
            }, {
              reciteIndex: newIndex
            })
            break
          case this.config.examTypeDict[1]:
            storage[this.lib] = Object.assign({
              ...storage[this.lib]
            }, {
              practiceIndex: newIndex
            })
            break
        }
        uni.setStorageSync('sv-exam', storage)
      },
      getIndex() {
        let index = 0
        const storage = uni.getStorageSync('sv-exam')
        try {
          if (!this.lib) throw new Error('lib is undefined')
          if (!this.type) throw new Error('type is undefined')
          switch (this.type) {
            case config.examTypeDict[0]:
              index = storage[this.lib].reciteIndex || 0
              break
            case config.examTypeDict[1]:
              index = storage[this.lib].practiceIndex || 0
              break
            case config.examTypeDict[2]:
              index = 0
              break
          }
        } catch (e) {
          // 当缓存中缺失部分参数时，默认归零
          index = 0
        }
        return index
      }
    }
  }
</script>

<style lang="scss">
  .sv-exam {
    --bg-color: #ffffff; // 主要背景
    --sub-bg-color: rgba(0, 216, 134, 0.1); // 次要背景
    --border-color: #e6e6e6; // 边框色
    --border-highlight-color: #01beff; // 边框高亮色
    --primary-color: #01beff; // 行为配色
    --success-color: #00d886; // 行为配色
    --warning-color: #ff0808; // 行为配色
    --error-color: #ff444f; // 行为配色
    --info-color: rgba(0, 216, 134, 0.1); // 行为配色
    --card-height: 50vh; // 答题卡高度

    // --card-header-height: #{v-bind(cardHeaderHeight)}; // 答题卡头部高度
    // 单元单位建议非必要勿修改，使用rpx会存在一些样式问题，这里统一使用px
    // --paper-unit-12: 24rpx; // 单元尺寸 12px
    // --paper-unit-16: 32rpx; // 单元尺寸 16px
    --paper-unit-12: 12px; // 单元尺寸 12px
    --paper-unit-16: 16px; // 单元尺寸 16px

    width: 100%;
    height: 100%;
    box-sizing: border-box;
    font-size: 14px;

    .exam-empty-loading {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;

      .exam-loading-text {
        font-size: var(--paper-unit-12);
        line-height: 2.4;
      }
    }
  }

  .primary-color {
    color: var(--primary-color);
  }

  .success-color {
    color: var(--success-color);
  }

  .warning-color {
    color: var(--warning-color);
  }

  .error-color {
    color: var(--error-color);
  }

  .info-color {
    color: var(--info-color);
  }

  // loading动画
  .exam-loading-cube {
    --size: 10px;
    --color: white;
    width: 20px;
    height: 20px;
    position: relative;
  }

  .exam-loading-cube::after,
  .exam-loading-cube::before {
    box-sizing: border-box;
    position: absolute;
    content: '';
    width: var(--size);
    height: var(--size);
    top: 50%;
    animation: exam-loading-cube-up 2.4s cubic-bezier(0, 0, 0.24, 1.21) infinite;
    left: 50%;
    background: var(--color);
    box-shadow: 0 0 calc(var(--size) / 3) rgba(0, 0, 0, 0.25);
  }

  .exam-loading-cube::after {
    background: var(--color);
    top: calc(50% - var(--size));
    left: calc(50% - var(--size));
    animation: exam-loading-cube-down 2.4s cubic-bezier(0, 0, 0.24, 1.21) infinite;
  }

  @keyframes exam-loading-cube-down {

    0%,
    100% {
      transform: none;
    }

    25% {
      transform: translateX(100%);
    }

    50% {
      transform: translateX(100%) translateY(100%);
    }

    75% {
      transform: translateY(100%);
    }
  }

  @keyframes exam-loading-cube-up {

    0%,
    100% {
      transform: none;
    }

    25% {
      transform: translateX(-100%);
    }

    50% {
      transform: translateX(-100%) translateY(-100%);
    }

    75% {
      transform: translateY(-100%);
    }
  }
</style>